package com.wayz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.wayz.constants.CShortMessageType;
import com.wayz.constants.ShortMessageStatus;
import com.wayz.exception.WayzException;
import com.wayz.mapper.DShortMessageDAO;
import com.wayz.service.SmsService;
import com.wayz.sms.entity.DShortMessage;
import com.wayz.sms.redis.RShortMessageId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 短信服务实现类
 *
 * @author wade.liu@wayz.ai
 */
@Service("smsService")
public class SmsServiceImpl implements SmsService {
    /** 属性相关 */
    /** 短信API产品域名 */
    @Value("${sms.domain}")
    private String smsDomain = null;
    /** 短信网关KeyId */
    @Value("${sms.accessKeyId}")
    private String smsAccessKeyId = null;
    /** 短信网关秘钥 */
    @Value("${sms.accessSecret}")
    private String smsAccessSecret = null;
    /** 短信区域 */
    @Value("${sms.regionId}")
    private String smsRegionId = null;
    /** 短信签名 */
    @Value("${sms.signName}")
    private String smsSignName = null;
    /** 短消息类型列表 */
    @Value("${sms.type.list}")
    private String typeList = null;
    /** 短消息模板列表 */
    @Value("${sms.template.list}")
    private String templateList = null;

    /** 日志相关 */
    private static final Logger LOGGER = LoggerFactory.getLogger(SmsServiceImpl.class);


    /** 标识相关 */
    /**
     * 短消息标识
     */
    @Resource(name = "rShortMessageId")
    private RShortMessageId rShortMessageId = null;

    /** DAO相关 */
    /** 短消息DAO */
    @Resource(name = "dShortMessageDAO")
    private DShortMessageDAO dShortMessageDAO = null;

    /** 短消息类型模板 */
    private Map<Short, String> typeMap = new HashMap<Short, String>();


    /**
     * 加载短消息类型模板
     *
     * @throws YungeException
     */
    @PostConstruct
    public void loadSmsTypeTemplate() throws WayzException {
        String[] types = typeList.split(",");
        String[] templates = templateList.split(",");
        for (int i = 0; i < types.length; i++) {
            typeMap.put(Short.parseShort(types[i]), templates[i]);
        }
    }

    /**
     * 发送消息
     *
     * @param phone   电话号码
     * @param type    短信类型
     * @param content 短信内容
     */
    @Override
    public void sendMessage(String phone, Short type, String content) throws WayzException {
        // 获取标识
        Long messageId = rShortMessageId.increment();
        Map mapContent = new HashMap<String, String>();
        String[] strs = content.split(",");
        switch (type) {
            case CShortMessageType.REGISTER: {
                mapContent.put("code", strs[0]);
                mapContent.put("product", "媒体SaaS服务平台");
                break;
            }
            case CShortMessageType.RETRIEVE: {
                mapContent.put("code", strs[0]);
                break;
            }
            case CShortMessageType.BIND_PHONE: {
                mapContent.put("code", strs[0]);
                break;
            }
            case CShortMessageType.UNBIND_PHONE: {
                mapContent.put("code", strs[0]);
                break;
            }
            case CShortMessageType.POSITION_EXPIRE: {
                mapContent.put("name", strs[0]);
                mapContent.put("count", strs[1]);
                break;
            }
        }
        // 保存消息
        DShortMessage dMessageCreate = new DShortMessage();
        dMessageCreate.setStatus(ShortMessageStatus.SENDING);
        dMessageCreate.setType(type);
        dMessageCreate.setPhone(phone);
        dMessageCreate.setContent(content);
        dMessageCreate.setCause(null);
        dShortMessageDAO.create(messageId, dMessageCreate);

        //推送消息
        try {
            // 调用接口
            sendMessage(phone, typeMap.get(type), mapContent);

            // 修改状态
            DShortMessage dMessageModify = new DShortMessage();
            dMessageModify.setId(messageId);
            dMessageModify.setStatus(ShortMessageStatus.SUCCESS);
            dShortMessageDAO.modify(dMessageModify);
        }
        catch (Exception e) {
            // 修改结果
            DShortMessage dMessageModify = new DShortMessage();
            dMessageModify.setId(messageId);
            dMessageModify.setStatus(ShortMessageStatus.FAILURE);
            dMessageModify.setCause(e.getMessage());
            dShortMessageDAO.modify(dMessageModify);

            // 抛出异常
            throw new WayzException(e);
        }
    }

    /**
     * 发送消息
     *
     * @param phone 电话号码
     * @param template 短信模板
     * @throws ClientException
     * @throws ServerException
     */
    private void sendMessage(String phone, String template, Map valMap) throws WayzException, ServerException,
            ClientException {
        // 初始化
        DefaultProfile profile = DefaultProfile.getProfile(smsDomain, smsAccessKeyId, smsAccessSecret);
        DefaultProfile.addEndpoint(smsRegionId, smsRegionId, "Dysmsapi", "dysmsapi.aliyuncs.com");
        IAcsClient client = new DefaultAcsClient(profile);

        SendSmsRequest request = new SendSmsRequest();
        request.setMethod(MethodType.POST);
        request.setPhoneNumbers(phone);
        request.setRegionId(smsRegionId);
        request.setSecurityToken(smsAccessSecret);
        request.setSignName(smsSignName);
        request.setTemplateCode(template.toString());
        request.setTemplateParam(JSONObject.toJSONString(valMap));

        // 发送
        SendSmsResponse response = client.getAcsResponse(request);

        // 解析应答
        if (response.getCode() != null && response.getCode().equals("OK")) {
            // 请求成功
            LOGGER.debug("短信发送成功:" + phone);
        }
        else {
            // 异常返回输出错误码和错误信息
            String errmsgString = "错误码=" + response.getCode() + " 错误信息= " + response.getMessage();
            LOGGER.error(errmsgString);
            throw new WayzException(errmsgString);
        }
    }
}
